﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Animation;
using System.Windows.Media.Media3D;
using TestAppliWPF.Files;
using System.IO;
using System.Xml;

namespace TestAppliWPF
{
    /// <summary>
    /// Logique d'interaction pour MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private const string DebugPath = @"..\..\";
        private const string DatabasePath = DebugPath + @"Databases";
        private const string MainMenuFile = DatabasePath + @"\Main Menu\Main Menu.xml";

        // Icon sizes in window mode
        const int SYSTEM_ICON_WIDTH = 305;
        const int SYSTEM_ICON_HEIGHT = 305;
        const double OPACITY_SELECTED = 1.00;
        const double OPACITY_UNSELECTED = 0.30;

        const int MAIN_MENU = 0;
        const int SYSTEM_MENU = 1;

        public List<Image> systemImageList;
        private List<GamingSystem> gamingSystems;
        public int selectedSystem;
        public int currentMenu;

        public MainWindow()
        {
            InitializeComponent();

            gamingSystems = new List<GamingSystem>();
            ReadMainMenu();

            // Key handlers
            this.PreviewKeyDown += new KeyEventHandler(HandleKeyDown);

            // Inits
            this.LoadSystemImages();

            // Init
            currentMenu = MAIN_MENU;

        }

        private void LoadSystemImages()
        {
            if (systemImageList == null)
            {
                systemImageList = new List<Image>();
            }

            List<String> imageSrcList = new List<string>();
            
            imageSrcList.Add("Amiga CD32.png");
            imageSrcList.Add("Atari 2600 Jr.png");
            imageSrcList.Add("Atari 2600.png");
            imageSrcList.Add("Atari 5200.png");
            imageSrcList.Add("Atari 7800.png");
            imageSrcList.Add("Atari Jaguar CD.png");
            imageSrcList.Add("Atari Jaguar.png");
            imageSrcList.Add("Atari Lynx.png");
            imageSrcList.Add("FM Towns Marty.png");
            imageSrcList.Add("NEC PCFX.png");
            imageSrcList.Add("NEC TurboDuo.png");
            imageSrcList.Add("NEC TurboGrafx CD.png");
            imageSrcList.Add("Nintendo DS.png");
            imageSrcList.Add("Nintendo Game Boy Advance.png");
            imageSrcList.Add("Nintendo Game Boy Color.png");
            imageSrcList.Add("Nintendo Game Boy.png");
            imageSrcList.Add("Nintendo GameCube.png");
            imageSrcList.Add("Nintendo N64.png");
            imageSrcList.Add("Nintendo NES3.png");
            imageSrcList.Add("Nintendo SNES2.png");
            imageSrcList.Add("Panasonic 3DO.png");
            imageSrcList.Add("Philips CDi 450.png");
            imageSrcList.Add("Sega CD.png");
            imageSrcList.Add("Sega CDX.png");
            imageSrcList.Add("Sega Dreamcast.png");
            imageSrcList.Add("Sega Game Gear.png");
            imageSrcList.Add("Sega Master System II.png");
            imageSrcList.Add("Sega MegaDrive II.png");
            imageSrcList.Add("Sega Saturn.png");
            imageSrcList.Add("SNK Neo-Geo CDZ.png");
            imageSrcList.Add("SNK Neo-Geo.png");
            imageSrcList.Add("Sony PS2.png");
            imageSrcList.Add("Sony PSone.png");

            int index = 0;
            foreach (String imgSrc in imageSrcList)
            {
                Image image = new Image();
                BitmapImage bitmapImage = new BitmapImage();
                bitmapImage.BeginInit();
                bitmapImage.UriSource = new Uri("/Images/" + imgSrc, UriKind.Relative);
                bitmapImage.EndInit();

                image.Source = bitmapImage;
                image.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
                image.VerticalAlignment = System.Windows.VerticalAlignment.Top;
                //image.Height = 305;
                //image.Width = 305;
                
                image.Name = "image" + index;
                //image.Stretch = Stretch.UniformToFill;

                //image.Opacity = 0.0;
                image.Opacity = 0.5;

                systemImageList.Add(image);

                this.mainMenu.Children.Add(image);
                index++;
            }

            selectedSystem = 0;

            Redraw();
        }

        private void HandleKeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.Escape:
                    EscapeCurrentMenu();
                    break;
                case Key.Left:
                    GoLeft();
                    break;
                case Key.Right:
                    GoRight();
                    break;
                case Key.Up:
                    GoUp();
                    break;
                case Key.Down:
                    GoDown();
                    break;
            }

            if (((Keyboard.Modifiers & ModifierKeys.Alt) > 0) 
                && (e.Key == Key.Return || (e.Key == Key.System && e.SystemKey == Key.Return)))
            {
                ToggleFullscreen();
                
            }
        }

        private void EscapeCurrentMenu()
        {
            switch (currentMenu)
            {
                case MAIN_MENU:
                    Close();
                    break;
                case SYSTEM_MENU:
                    break;
            }
        }

        private void ToggleFullscreen()
        {
            if (this.WindowState != WindowState.Maximized)
            {
                // Switch to fullscreen mode
                this.WindowStyle = WindowStyle.None;
                this.WindowState = WindowState.Maximized;

                // Resize images
                Redraw();
            }
            else
            {
                // Switch to windowed mode
                this.WindowStyle = WindowStyle.SingleBorderWindow;
                this.WindowState = WindowState.Normal;

                // Resize images
                Redraw();
            }
        }

        private void Redraw()
        {
            // Resize grid
            mainMenu.Height = this.Height * 0.15; // main menu is 10% of the total height
            mainMenu.Width = this.Width;
            mainMenu.Margin = new Thickness(0, mainMenu.Height * 2, 0, 0);

            int index = 0;
            double offset = 1.3*this.mainMenu.Height;
            foreach (Image image in systemImageList)
            {
                image.Height = mainMenu.Height;
                int drawOffset = index - selectedSystem + 1;
                if (drawOffset < -1)
                {
                    drawOffset += systemImageList.Count();
                }
                if (drawOffset > systemImageList.Count()-1)
                {
                    drawOffset -= systemImageList.Count();
                }

                int xpos = (int)(drawOffset * offset);
                image.Margin = new Thickness(xpos, 0, 0, 0);

                if (index == selectedSystem)
                {
                    image.Opacity = OPACITY_SELECTED;
                }
                else {
                    image.Opacity = OPACITY_UNSELECTED; 
                }

                index++;
            }
            selectionLabel.Margin = new Thickness(offset, 3 * mainMenu.Height, 0, 0);
            //selectionLabel.Content = "Selection " + selectedSystem;
            selectionLabel.Content = gamingSystems[selectedSystem%gamingSystems.Count].GetSystemName();
            selectionLabel.FontSize = 24 * mainMenu.Width/640;

            // Draw game list
            DrawGameList(gamingSystems[selectedSystem % gamingSystems.Count]);
        }

        private void DrawGameList(GamingSystem gamingSystem)
        {
            // TODO: improve this method
            gameList.Children.Clear();

            for(int i=0; i < gamingSystem.GetGameList().Count; i++)
            {
                Game game = gamingSystem.GetGameList()[i];

                Label gameTitle = new Label();

                gameTitle.Content = game.description;
                gameTitle.FontFamily = new FontFamily("Bauhaus 93");
                gameTitle.FontSize = 12 * mainMenu.Width / 640;
                gameTitle.Margin = new Thickness(0, gameTitle.FontSize * 1.2 * i, 0, 0);
                
                gameList.Children.Add(gameTitle);
            }



            //throw new NotImplementedException();
        }

        private void GoDown()
        {
            gamingSystems[selectedSystem].lastSelectedGame++;
            if (gamingSystems[selectedSystem].lastSelectedGame >= gamingSystems[selectedSystem].GetGameList().Count)
                gamingSystems[selectedSystem].lastSelectedGame -= gamingSystems[selectedSystem].GetGameList().Count;
            Redraw();
            //throw new NotImplementedException();
        }

        private void GoUp()
        {
            gamingSystems[selectedSystem].lastSelectedGame--;
            if (gamingSystems[selectedSystem].lastSelectedGame <= 0)
                gamingSystems[selectedSystem].lastSelectedGame += gamingSystems[selectedSystem].GetGameList().Count;
            Redraw();
            //throw new NotImplementedException();
        }

        private void GoRight()
        {
            selectedSystem = (selectedSystem + 1) % (systemImageList.Count());
            

            Redraw();
            //throw new NotImplementedException();
        }

        private void GoLeft()
        {
            selectedSystem--;
            if (selectedSystem < 0) selectedSystem += systemImageList.Count();
            systemImageList.Count();
            Redraw();
            //throw new NotImplementedException();


            //<BeginStoryboard>
            //    <Storyboard RepeatBehavior="Forever">
            //        <DoubleAnimation Storyboard.TargetName="myrect" 
            //           Storyboard.TargetProperty="Width" From="1" To="350" 
            //           Duration="0:0:1" BeginTime="0:0:0"/>
            //        <DoubleAnimation Storyboard.TargetName="myrect" 
            //           Storyboard.TargetProperty="Height" From="1" To="250" 
            //           Duration="0:0:1" BeginTime="0:0:1"/>
            //        <DoubleAnimation Storyboard.TargetName="myrect" 
            //           Storyboard.TargetProperty="Height" From="250" 
            //           To="1" Duration="0:0:1" BeginTime="0:0:2"/>
            //        <DoubleAnimation Storyboard.TargetName="myrect" 
            //           Storyboard.TargetProperty="Width" From="350" To="1" 
            //           Duration="0:0:1" BeginTime="0:0:3"/>
            //    </Storyboard>
            //</BeginStoryboard>

            //foreach (Image image in systemImageList)
            //{
            //    //DoubleAnimation oImageAngleAnimation = new DoubleAnimation();
            //    //oImageAngleAnimation.From = 0;
            //    //oImageAngleAnimation.To = 360;
            //    //oImageAngleAnimation.Duration = new Duration(new TimeSpan(0, 0, 0, 0, 500));
            //    //oImageAngleAnimation.RepeatBehavior = new RepeatBehavior(4);

            //    //TranslateTransform oTransform = new TranslateTransform(-100, 0);
            //    //oTransform.BeginAnimation(, oTransform);

            //    System.Windows.Point targetPoint = new System.Windows.Point();
            //    targetPoint.X = image.Margin.Left;
            //    //targetPoint.Y = clickPoint.Y - interactiveEllipse.Height / 2;

            //    var T = new TranslateTransform(-100, 0);
            //    Duration duration = new Duration(new TimeSpan(0, 0, 0, 1, 0));
            //    DoubleAnimation anim = new DoubleAnimation(targetPoint.X, duration);
            //    //T.BeginAnimation(TranslateTransform.XProperty, anim);
            //    T.BeginAnimation(TranslateTransform.XProperty, anim);

            //}



        }

        public void ReadMainMenu()
        {
            //List<GamingSystem> systemsList = new List<GamingSystem>();
            var listSystemes = new List<String>();

            if (File.Exists(MainMenuFile))
            {
                var fileContent = new StreamReader(MainMenuFile).ReadToEnd();

                // Create an XmlReader
                using (var reader = XmlReader.Create(new StringReader(fileContent)))
                {
                    // Parse the file and display each of the nodes.
                    while (reader.Read())
                    {
                        if (reader.NodeType == XmlNodeType.Element)
                        {
                            if (reader.Name == "game")
                            {
                                String systemName = reader.GetAttribute("name");
                                listSystemes.Add(systemName);
                                GamingSystem system = new GamingSystem(systemName);
                                gamingSystems.Add(system);
                            }
                        }
                    }
                }
            }
            else
            {
                throw new Exception("Le fichier de configuration du menu est absent.");
            }

            // Lire 
        }
    }
}
